#ifndef __SPI_H__
#define __SPI_H__

#ifdef __cplusplus
extern "C" {
#endif

#include "cfg.h"
#include "gpio.h"
#include "main.h"

#define CMD_PAGE_PROGRAM 0x02
#define CMD_READ_DATA_BYTES 0x03
#define CMD_READ_STA_REG 0x05
#define CMD_WRITE_ENABLE 0x06
#define CMD_SECTOR_ERASE 0x20
#define GET_DEVICE_ID 0x90
#define GET_IDENTIFICATION 0x9f

#define DUMMY_BYTE 0xff

#define SFLASH_ID 0xC84018  // Flash ID

#define SPI_CS_1                                                 \
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET) /* CS = 1 \
                                                        */
#define SPI_CS_0 \
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET) /* CS = 0 */

#define SPI_SCK_1 \
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET) /* SCK = 1 */
#define SPI_SCK_0 \
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET) /* SCK = 0 */

#define SPI_MOSI_1 \
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET) /* MOSI = 1 */
#define SPI_MOSI_0 \
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET) /* MOSI = 0 */

#define SPI_READ_MISO                                       \
    HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6) /* read MISO status \
                                         */

#define SPI_FLASH_NSS_ENABLE SPI_CS_0
#define SPI_FLASH_NSS_DISENABLE SPI_CS_1

#define SPI_FLASH_PAGE_SIZE 0x100  // 256 Byte
#define WIP_FLAG 0x01              /* write in progress(wip)flag */

#define DEVICE_SIZE 0x400000  // 4M
#define BLOCK_SIZE 0x10000    // 64K
#define SECTOR_SIZE 0x1000    // 4K
#define PAGE_SIZE 0x100       // 256

void MX_SPI1_Init(void);

uint16_t get_DeviceId(void);

void get_Identifica(uint8_t *data_out);

void get_ReadDataBytes(uint32_t dest_addr, uint8_t *data, uint32_t len);

void spi_flash_buffer_write(uint8_t *pbuffer, uint32_t write_addr,
                            uint16_t len);

void spi_read_cfg(dev_cfg_t *_cfg);

void spi_write_cfg(dev_cfg_t *_cfg);

#ifdef __cplusplus
}
#endif

#endif /* __SPI_H__ */
